<!--
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-04-12 15:15:44
 * @Description  : 分享页面左侧的侧边栏
-->

<template>
  <div class="pt-2 tree-panels-container">
    <n-tree
      block-line
      :data="options"
      :override-default-node-click-behavior="override"
      :render-label="renderLabel"
      :on-load="handleLoad"
      :node-props="nodeProps"
      :virtual-scroll="true"
      style="max-height: 90vh"
    />
    <n-dropdown
      placement="bottom-start"
      trigger="manual"
      :x="sourceDropDown.x"
      :y="sourceDropDown.y"
      :options="sourceDropDownOptions"
      :show="sourceDropDown.showDropdown"
      :on-clickoutside="handleSourceDropClickOutside"
      @select="handleSourceDropSelect"
      :render-label="renderSourceDropDownMenu"
    />
  </div>
</template>

<script setup lang="ts">
import type { TreeOverrideNodeClickBehavior, TreeOption } from 'naive-ui'
import useUserStore from '@/stores/modules/user'
import useExplorerStore from '@/stores/modules/explorer'
import { getLinkSourceByPage } from '@/api/source'
import type { IndexObj } from '@/types/commom'
import { navTypeList } from '@/constants/explorer'
import { arraysIsEqual } from '@/utils'
import { renderDropLabel } from '@/utils/commonBusiness'
import { useSourceAuth } from '@/hooks/useSourceAuth'
import { DropDownType, contextMenus } from '../../Explorer/constants/dropDown'

const emits = defineEmits<{
  (e: 'nodeClick', item: IndexObj): void
  (e: 'menuSelect', key: string, menu: IndexObj): void
}>()

const props = defineProps<{
  shareId: string
  options: IndexObj[]
}>()

const userStore = useUserStore()
const explorerStore = useExplorerStore()
const { sourceAuths, loadSourceAuth } = useSourceAuth()

onMounted(async () => {
  if (!userStore.userInfo) {
    await userStore.getUserInfo()
  }
})

const override: TreeOverrideNodeClickBehavior = ({ option }) => {
  if (!option.myIcon) {
    return 'toggleExpand'
  }
  return 'default'
}

const renderLabel = (info: {
  option: TreeOption
  checked: boolean
  selected: boolean
}) => {
  if (!info.option.myIcon) {
    return info.option.label
  }
  return renderDropLabel(
    info.option.myIcon as string,
    info.option.label as string
  )
}

const handleLoad = (node: IndexObj): Promise<void> => {
  // 对于文件类型
  if (node.myType === navTypeList.LINK_SHARE_DESC) {
    // 进行文件资源的加载
    return new Promise<void>((resolve) => {
      getLinkSourceByPage({
        code: explorerStore.linkShareCode,
        shareId: props.shareId,
        parentId: node.key as string,
        isDir: 1
      })
        .then((res) => {
          node.children = res.data.items.map((item) => {
            return {
              ...item,
              isLeaf: item.hasFolder === 0 || !!item.isLeaf,
              key: item.id,
              label: item.filename,
              myIcon: 'wenjianjia2',
              myType: navTypeList.LINK_SHARE_DESC
            }
          })
          resolve()
        })
        .catch(() => {
          node.children = []
          resolve()
        })
    })
  }

  // 对于其他类型的处理
  return new Promise<void>((resolve) => {
    setTimeout(() => {
      node.isLeaf = true
      resolve()
    }, 1000)
  })
}

// node被点击后的处理
const nodeProps = ({ option }: { option: IndexObj }) => {
  return {
    onClick(e: MouseEvent) {
      if (!option.myIcon) {
        return
      }
      emits('nodeClick', {
        ...option,
        label: option.label as string,
        key: option.key as string
      })
    },
    onContextmenu(e: MouseEvent) {
      curContextMenuOption.value = option
      const showContextMenu = () => {
        e.preventDefault()
        e.stopPropagation()
        sourceDropDown.showDropdown = false
        nextTick().then(() => {
          sourceDropDown.showDropdown = true
          sourceDropDown.x = e.clientX
          sourceDropDown.y = e.clientY
        })
      }

      if (option.myType === navTypeList.LINK_SHARE_DESC) {
        // TODO 获取用户对当前文档的权限，targetID为2时
        loadSourceAuth([option.key], 0)
        curRange.value = DropDownType.TREE_LINK_DESC
        showContextMenu()
      } else {
        return
      }
    }
  }
}

// 文件列表右键菜单
const curRange = ref('')
// 右键点击时，选择的项目
const curContextMenuOption = ref<IndexObj>({})
const renderSourceDropDownMenu = (option: IndexObj) => {
  return renderDropLabel(option.myIcon, option.label, '#888', '15px', '#13b1fe')
}

const sourceDropDown = reactive<IndexObj>({
  showDropdown: false,
  x: 0,
  y: 0
})

// 根据当前用户的权限信息和所处不同的树形位置确定最终的下拉菜单
const sourceDropDownOptions = computed(() => {
  let baseMenu: IndexObj[] = []

  if (userStore.userInfo) {
    baseMenu = contextMenus.filter((item) => {
      let res = true
      if (item.auth) {
        if (item.auth.role) {
          // 检查系统权限
          res =
            userStore.userInfo?.role.Permissions.some((v) => {
              return item.auth.role?.includes(v.ename)
            }) || false
          if (!res) {
            return res
          }
        }
        if (item.auth.doc) {
          // 检查文档权限
          res = sourceAuths.value.some((v) => {
            return item.auth.doc.includes(v)
          })

          if (!res) {
            return res
          }
        }

        if (item.auth.other) {
          // 检查其他
        }
      }
      if (item.range) {
        res = item.range.includes(curRange.value)
      }
      return res
    })
  } else {
    baseMenu = contextMenus.filter((item) => {
      if (item.auth) {
        return false
      } else {
        if (item.range) {
          return item.range.includes(curRange.value)
        } else {
          return true
        }
      }
    })
  }

  return baseMenu.filter((item) => {
    // 处理分割线
    if (item.type === 'divider' && item.needKey) {
      const keys = baseMenu
        .filter((item) => item.type !== 'divider')
        .map((v) => v.key)

      if (arraysIsEqual(keys, item.needKey)) {
        return false
      }
      return baseMenu.some((v) => item.needKey.includes(v.key))
    } else {
      return true
    }
  })
})

const handleSourceDropClickOutside = () => {
  sourceDropDown.showDropdown = false
}

// 右键菜单项被选择
const handleSourceDropSelect = (key: string) => {
  sourceDropDown.showDropdown = false
  if (key === 'reflesh-tree') {
    // 刷新树目录，进行文件节点的加载
    handleLoad(curContextMenuOption.value)
  }
  // 部分类型需要给父亲处理，传递给父组件一个node即可
  emits('menuSelect', key, curContextMenuOption.value)
}
</script>

<style scoped lang="scss">
.tree-panels-container {
  :deep(.n-tree .n-tree-node) {
    height: 30px;
    align-items: center;
  }

  :deep(.n-tree-node-wrapper) {
    padding: 0;
  }
}
</style>
